package com.hfi.restful.web.async;

import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;

/**
 * @author ChangLiang
 * @date 2019/8/1
 */
@RestController
public class AsyncController {

    private Logger LOGGER = LoggerFactory.getLogger(getClass());

    @Autowired
    private MockQueue mockQueue;

    @Autowired
    private DeferredResultHolder deferredResultHolder;

    /**
     * 模拟同步下单
     * @return
     * @throws InterruptedException
     */
    /*@RequestMapping("/order")
    public String order() throws InterruptedException {
        LOGGER.info("tomcat主线程开始");
        Thread.sleep(1000);
        LOGGER.info("tomcat主线程结束");
        return "success";
    }*/

    /**
     * 使用Callable来启动副线程
     * 在这个过程中 tomcat主线程仍然可以去接受请求
     * @return
     */
    /*@RequestMapping("/order")
    public Callable<String> order() {
        LOGGER.info("tomcat主线程开始");
        Callable<String> result = new Callable<String>() {
            @Override
            public String call() throws Exception {
                LOGGER.info("副线程开始");
                Thread.sleep(1000);
                LOGGER.info("副线程返回");
                return "success";
            }
        };
        LOGGER.info("tomcat主线程结束");
        return result;
    }*/

    /**
     * 使用DeferredResult
     * 在这段代码中 你是看不到有另外一个线程在处理deferedResultHolder中的DeferredResult的
     * @return
     * @throws Exception
     */
    @RequestMapping("/order")
    public DeferredResult<String> order() throws Exception {
        // 应用1的tomcat主线程来接收http请求
        LOGGER.info("tomcat主线程开始");
        String orderNumber = RandomStringUtils.randomNumeric(8);
        // 模拟将订单放到消息队列中
        mockQueue.setPlaceOrder(orderNumber);

        DeferredResult<String> result = new DeferredResult<>();

        // 把订单号作为key 放到deferredResultHolder中
        deferredResultHolder.getMap().put(orderNumber, result);
        LOGGER.info("tomcat主线程结束");
        return result;
    }
}
